package com.zq.it.cms;

import javax.servlet.MultipartConfigElement;

import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

import com.zq.it.cms.support.ForeInterceptor;

@Configuration
@EnableAutoConfiguration
@EntityScan({"com.zq.it.cms.domain"})
@EnableJpaRepositories(basePackages = {"com.zq.it.cms.repository"})
@ComponentScan({ "com.zq.it.cms.web.fore", "com.zq.it.cms.service"})
@Import({ShiroConfig.class, ContextConfig.class, MenuConfig.class})
public class CmsApplication extends SpringBootServletInitializer implements WebApplicationInitializer{

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
		return configureApplication(builder);
	}

	public static void main(String[] args) throws Exception {
		configureApplication(new SpringApplicationBuilder()).run(args);
	}
	
	@Bean(name = "backendDispatcherServlet")
	public DispatcherServlet backendDispatcherServlet() {
		AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext();
		// 使用BackendWebConfig作为配置类
		servletAppContext.register(BackendWebConfig.class);
		DispatcherServlet dispatcherServlet = new DispatcherServlet(servletAppContext);
		return dispatcherServlet;
	}

	@Bean(name = "backendDispatcherServletRegistration")
	public ServletRegistrationBean backendDispatcherServletRegistration(ObjectProvider<MultipartConfigElement> multipartConfigProvider) {
		ServletRegistrationBean registration = new ServletRegistrationBean(backendDispatcherServlet(), "/admin/*" , "/admin");
		// 必须指定启动优先级，否则无法生效
		registration.setLoadOnStartup(1);
		registration.setName("backendDispatcherServlet");
		// 注册上传配置对象，否则后台不能处理上传
		MultipartConfigElement multipartConfig = multipartConfigProvider.getIfAvailable();
		if (multipartConfig != null) {
			registration.setMultipartConfig(multipartConfig);
		}
		return registration;
	}
	
	private static SpringApplicationBuilder configureApplication(SpringApplicationBuilder builder) {
		return builder.sources(CmsApplication.class).listeners(new ApplicationListener<ApplicationEnvironmentPreparedEvent>() {
			@Override
			public void onApplicationEvent(ApplicationEnvironmentPreparedEvent event) {
				
			}
		});
	}
	
	@Configuration
	protected static class WebConfig extends WebMvcConfigurerAdapter {
		
		@Bean
		public ForeInterceptor foreInterceptor() {
			return new ForeInterceptor();
		}

		@Override
		public void addInterceptors(InterceptorRegistry registry) {
			registry.addInterceptor(foreInterceptor()).excludePathPatterns("/error/**");
			super.addInterceptors(registry);
		}
		
	}
}
